package org.example.dao;

import org.example.model.Address;
import org.example.util.DBUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class AddressDAOImpl implements AddressDAO {
    
    @Override
    public List<Address> findByUserId(Integer userId) {
        List<Address> addresses = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            conn = DBUtil.getConnection();
            String sql = "SELECT * FROM tb_address WHERE user_id = ? ORDER BY is_default DESC, address_id DESC";
            System.out.println("Executing SQL: " + sql + " with userId: " + userId);
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, userId);
            rs = pstmt.executeQuery();
            
            while (rs.next()) {
                Address address = new Address();
                address.setAddressId(rs.getInt("address_id"));
                address.setUserId(rs.getInt("user_id"));
                address.setReceiver(rs.getString("receiver_name"));
                address.setPhone(rs.getString("phone"));
                address.setProvince(rs.getString("province"));
                address.setCity(rs.getString("city"));
                address.setDistrict(rs.getString("district"));
                address.setDetailAddress(rs.getString("detail_address"));
                address.setIsDefault(rs.getBoolean("is_default"));
                addresses.add(address);
                System.out.println("Found address: " + address.getReceiver() + " - " + address.getDetailAddress());
            }
        } catch (SQLException e) {
            System.out.println("Error in findByUserId: " + e.getMessage());
            e.printStackTrace();
        } finally {
            DBUtil.closeAll(rs, pstmt, conn);
        }
        
        System.out.println("Returning " + addresses.size() + " addresses");
        return addresses;
    }
    
    @Override
    public Address findById(Integer addressId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Address address = null;
        
        try {
            conn = DBUtil.getConnection();
            String sql = "SELECT * FROM tb_address WHERE address_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, addressId);
            rs = pstmt.executeQuery();
            
            if (rs.next()) {
                address = new Address();
                address.setAddressId(rs.getInt("address_id"));
                address.setUserId(rs.getInt("user_id"));
                address.setReceiver(rs.getString("receiver_name"));
                address.setPhone(rs.getString("phone"));
                address.setProvince(rs.getString("province"));
                address.setCity(rs.getString("city"));
                address.setDistrict(rs.getString("district"));
                address.setDetailAddress(rs.getString("detail_address"));
                address.setIsDefault(rs.getBoolean("is_default"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeAll(rs, pstmt, conn);
        }
        
        return address;
    }
    
    @Override
    public boolean save(Address address) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 如果设置为默认地址，先将其他地址设置为非默认
            if (address.getIsDefault()) {
                String updateSql = "UPDATE tb_address SET is_default = 0 WHERE user_id = ?";
                pstmt = conn.prepareStatement(updateSql);
                pstmt.setInt(1, address.getUserId());
                pstmt.executeUpdate();
            }
            
            String sql = "INSERT INTO tb_address (user_id, receiver_name, phone, province, city, district, detail_address, is_default) " +
                        "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, address.getUserId());
            pstmt.setString(2, address.getReceiver());
            pstmt.setString(3, address.getPhone());
            pstmt.setString(4, address.getProvince());
            pstmt.setString(5, address.getCity());
            pstmt.setString(6, address.getDistrict());
            pstmt.setString(7, address.getDetailAddress());
            pstmt.setInt(8, address.getIsDefault() ? 1 : 0);
            
            int result = pstmt.executeUpdate();
            conn.commit();
            return result > 0;
        } catch (SQLException e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            DBUtil.closeAll(null, pstmt, conn);
        }
    }
    
    @Override
    public boolean update(Address address) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 如果设置为默认地址，先将其他地址设置为非默认
            if (address.getIsDefault()) {
                String updateSql = "UPDATE tb_address SET is_default = 0 WHERE user_id = ?";
                pstmt = conn.prepareStatement(updateSql);
                pstmt.setInt(1, address.getUserId());
                pstmt.executeUpdate();
            }
            
            String sql = "UPDATE tb_address SET receiver_name = ?, phone = ?, province = ?, city = ?, " +
                        "district = ?, detail_address = ?, is_default = ? WHERE address_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, address.getReceiver());
            pstmt.setString(2, address.getPhone());
            pstmt.setString(3, address.getProvince());
            pstmt.setString(4, address.getCity());
            pstmt.setString(5, address.getDistrict());
            pstmt.setString(6, address.getDetailAddress());
            pstmt.setInt(7, address.getIsDefault() ? 1 : 0);
            pstmt.setInt(8, address.getAddressId());
            
            int result = pstmt.executeUpdate();
            conn.commit();
            return result > 0;
        } catch (SQLException e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            DBUtil.closeAll(null, pstmt, conn);
        }
    }
    
    @Override
    public boolean delete(Integer addressId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try {
            conn = DBUtil.getConnection();
            String sql = "DELETE FROM tb_address WHERE address_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, addressId);
            
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        } finally {
            DBUtil.closeAll(null, pstmt, conn);
        }
    }
    
    @Override
    public boolean setDefault(Integer userId, Integer addressId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 先将所有地址设置为非默认
            String updateSql = "UPDATE tb_address SET is_default = 0 WHERE user_id = ?";
            pstmt = conn.prepareStatement(updateSql);
            pstmt.setInt(1, userId);
            pstmt.executeUpdate();
            
            // 将指定地址设置为默认
            String sql = "UPDATE tb_address SET is_default = 1 WHERE address_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, addressId);
            
            int result = pstmt.executeUpdate();
            conn.commit();
            return result > 0;
        } catch (SQLException e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            DBUtil.closeAll(null, pstmt, conn);
        }
    }
} 